#include <SDL.h>
#include <SDL_image.h>

#include <SDL_opengl.h>


/* Quick utility function for texture creation */
static int power_of_two(int input)
{
  int value = 1;

  while ( value < input ) {
	value <<= 1;
  }
  return value;
}

GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
{
  GLuint texture;
  int w, h;
  SDL_Surface *image;
  SDL_Rect area;
  Uint32 saved_flags;
  Uint8  saved_alpha;

  /* Use the surface width and height expanded to powers of 2 */
  w = power_of_two(surface->w);
  h = power_of_two(surface->h);
  texcoord[0] = 0.0f;         /* Min X */
  texcoord[1] = 0.0f;         /* Min Y */
  texcoord[2] = (GLfloat)surface->w / w;  /* Max X */
  texcoord[3] = (GLfloat)surface->h / h;  /* Max Y */

  image = SDL_CreateRGBSurface(
							   SDL_SWSURFACE,
							   w, h,
							   32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
							   0x000000FF,
							   0x0000FF00,
							   0x00FF0000,
							   0xFF000000
#else
							   0xFF000000,
							   0x00FF0000,
							   0x0000FF00,
							   0x000000FF
#endif
							   );
  if ( image == NULL ) {
	return 0;
  }

  /* Save the alpha blending attributes */
  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
  saved_alpha = surface->format->alpha;
  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
	SDL_SetAlpha(surface, 0, 0);
  }

  /* Copy the surface into the GL texture image */
  area.x = 0;
  area.y = 0;
  area.w = surface->w;
  area.h = surface->h;
  SDL_BlitSurface(surface, &area, image, &area);

  /* Restore the alpha blending attributes */
  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
	SDL_SetAlpha(surface, saved_flags, saved_alpha);
  }

  /* Create an OpenGL texture for the image */
  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_2D, texture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_2D,
			   0,
			   GL_RGBA,
			   w, h,
			   0,
			   GL_RGBA,
			   GL_UNSIGNED_BYTE,
			   image->pixels);
  SDL_FreeSurface(image); /* No longer needed */

  return texture;
}



int main(int argc, char ** argv) { 

  int error;
  error = SDL_Init(SDL_INIT_EVERYTHING);

  int size;
  glGetIntegerv( GL_MAX_TEXTURE_SIZE, & size ) ;
  
  

  /* SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); */

  /* SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); */

  /* SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); */
  /* SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); */
  /* SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); */
  /* SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); */

  SDL_Surface* drawContext;
  Uint32 flags;

  flags = SDL_OPENGL;
  // flags = SDL_OPENGL | SDL_FULLSCREEN;
  drawContext = SDL_SetVideoMode(480, 640, 0, flags);

  

  glViewport( 0, 0, ( GLsizei )480, ( GLsizei )640 );

  glMatrixMode( GL_PROJECTION );
  glLoadIdentity( );

  //gluPerspective( 45.0f, (GLfloat)480/(GLfloat)640, 0.1f, 100.0f );
  glOrtho(0,480,640,0,-1,1);

  glMatrixMode( GL_MODELVIEW );
  glClearDepth( 1.0f );
  /* Enables Depth Testing */
  glEnable( GL_DEPTH_TEST );
  glEnable( GL_TEXTURE_2D );
  

  /* The Type Of Depth Test To Do */
  glDepthFunc( GL_LEQUAL );

  float texturecoords[4];

  char *file="../data/tube.png";
  SDL_Surface *image;
  image=IMG_Load(file);
  if ( image == NULL ) {
	fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
	return -1;
  }


  int texture;
  texture=SDL_GL_LoadTexture(image, texturecoords);

  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // scale linearly when image bigger than texture
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // scale linearly when image smalled than texture

																 
  glBindTexture( GL_TEXTURE_2D, texture );


  float x=0,y=0;
  while (1) { 
	SDL_Event event;

    while ( SDL_PollEvent(&event) ) {
	  switch (event.type) {
	  case SDL_MOUSEMOTION:
		printf("Mouse moved by %d,%d to (%d,%d)\n", 
			   event.motion.xrel, event.motion.yrel,
			   event.motion.x, event.motion.y);
		break;
	  case SDL_MOUSEBUTTONDOWN:
		printf("Mouse button %d pressed at (%d,%d)\n",
			   event.button.button, event.button.x, event.button.y);
		break;
	  case SDL_QUIT:
		exit(0);
	  }
    }
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear The Screen And The Depth Buffer
	glLoadIdentity();						// Reset The View

	glTranslatef(x,y,0.0f);	
	x+=0.01;
	if (x>480) { y+=20; x=0;}

	glBegin(GL_QUADS);						// Draw A Quad

	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(10.0f, 500.0f, 0.0f);				// Top Left

	glTexCoord2f(1.0f, 1.0f);
	glVertex3f( 500.0f, 500.0f, 0.0f);				// Top Right

	glTexCoord2f(1.0f, 0.0f);
	glVertex3f( 500.0f,10.0f, 0.0f);				// Bottom Right

	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(10.0f,10.0f, 0.0f);				// Bottom Left

	glEnd();							// Done Drawing The Quad

	/* glBegin(GL_QUADS);						// Draw A Quad */
	/* glColor3f(1.0f,0.0f,0.0f); */
	/* 	glVertex3f(-1.0f, 1.0f, 0.0f);				// Top Left */
	/* 	glColor3f(0.0f,1.0f,0.0f); */
	/* 	glVertex3f( 1.0f, 1.0f, 0.0f);				// Top Right */
	/* 	glColor3f(1.0f,1.0f,0.0f); */
	/* 	glVertex3f( 1.0f,-1.0f, 0.0f);				// Bottom Right */
	/* 	glColor3f(0.0f,0.0f,1.0f); */
	/* 	glVertex3f(-1.0f,-1.0f, 0.0f);				// Bottom Left */
	/* glEnd();							// Done Drawing The Quad */


	SDL_GL_SwapBuffers();
  }
  // SDL_Quit();
 
}
